<?php

namespace App\Http\Controllers\Api;


use App\Excels;
use App\Files;
use App\Http\Services\MerchantManager;
use App\Imports\ExcelCheck;
use App\Jobs\StandardMedicineImportHandler;
use App\User;
use DB;
use Excel;
use Exception as E;
use File;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Log;
use Storage;
use Redis;

class ExcelController extends Controller
{
    public function uploadExcel(Request $request){
        $uploadFile  = $request->file('file');

        if(!$request->hasFile('file'))
            return response()->json(['level'=>'error','message'=>'参数错误']);

        if(!$uploadFile->isValid())
            return response()->json(['level'=>'error','message'=>'文件上传失败']);

        $fileName = $uploadFile->getClientOriginalName();

        $fileMd5 = md5_file($uploadFile);
        $fileType = File::extension($fileName);
        if (!in_array(strtolower($fileType),['xls','xlsx','csv','tsv','ods','slk','xml','gnumeric','html']))
            return response()->json(['level'=>'error','message'=>'文件格式暂不支持']);
        $disk='local';
        $toDirPath = 'excel';
        $toFilePath = $toDirPath.'/'.$fileMd5.'.'.$fileType;
        if(!Storage::disk($disk)->exists($toDirPath)){
            Storage::disk($disk)->makeDirectory($toDirPath);
        }
        try{
            if(!Storage::disk($disk)->exists($toFilePath)){
                Storage::disk($disk)->put($toFilePath,File::get($uploadFile));
            }
        } catch (E $exception){
            Log::error('uploadCert:'.$exception->getMessage());
            return response()->json(['level'=>'error','message'=>'上传发生错误：'.$exception->getMessage(),'data'=>'']);
        }

        File::delete($uploadFile);
        $fileSize = Storage::disk($disk)->size($toFilePath);
        $mimeType = Storage::disk($disk)->mimeType($toFilePath);

        $files = Files::whereFileMd5($fileMd5)->whereFileSize($fileSize)->first();
        if(!$files){
            $files = new Files();
            $files->file_name = $fileName;
            $files->file_url  = $toDirPath;
            $files->file_type = '.'.$fileType;
            $files->file_md5  = $fileMd5;
            $files->file_size = $fileSize;
            $files->file_ext  = $mimeType;
            $files->disk      = $disk;
            $files->save();
        }
        $theExcel = new Excels();
        $theExcel->file_id = $files->id;
        $theExcel->key     = $files->file_md5;
        $theExcel->excel_name = $files->file_name;
        $theExcel->excel_type = $files->file_type;
        $theExcel->save();

        return response()->json(['level'=>'success','message'=>'上传成功','data'=>$theExcel]);
    }

    public function checkExcel(Request $request){
        $time=microtime(1);
        /** @var User $merchantUser */
        $merchantUser = MerchantManager::isLogin($request);
        if(!$merchantUser)
            return response()->json(['level' => 'error','message' => '请先登录！','data' => 'no_login']);
        $excel_id       = $request->input('excel_id');
        $merchant_id    = $request->input('merchant_id',0);

        if (!$excel_id)
            return response()->json(['level'=>'error','message'=>'参数错误','data'=>'']);
        if ($merchant_id && !is_numeric($merchant_id))
            return response()->json(['level'=>'error','message'=>'门店id参数错误','data'=>'']);

        $thisExcel = Excels::whereId($excel_id)->first();
        if (!$thisExcel)
            return response()->json(['level'=>'error','message'=>'excel不存在','data'=>'']);

        $enterpriseInfo = MerchantManager::getMerchantInfoByUserId($merchantUser->id);
        if(!$enterpriseInfo)
            return response()->json(['level' => 'error','message' => '商家信息异常']);

        $filePath = storage_path() . '/app/excel/'.$thisExcel->key.$thisExcel->excel_type;
        Log::notice('checkExcel,$filePath=>'.$filePath);
//        $filePath = storage_path() . '/app/excel/xn.xlsx';
        $excelCheck = new ExcelCheck($enterpriseInfo->id,$merchant_id);
        Excel::import($excelCheck,$filePath);
        $payload = [
            'error_message' =>$excelCheck->getErrorMessage(),
            'notice'        =>$excelCheck->getNotice(),
            'check_finish_in'=>(microtime(1) - $time).'秒'
        ];
        try {
            if (count($payload['error_message']) > 0){
                return response()->json(['level'=>'error','message'=>'excel检查到错误，请修正后再试','data'=>$payload]);
            } else {
                DB::beginTransaction();
                $checkResult = \App\ExcelCheck::whereUserId($merchantUser->id)
                    ->whereExcelId($excel_id)
                    ->whereEnterpriseId($enterpriseInfo->id)
                    ->whereMerchantId($merchant_id)
                    ->orderByDesc('id')
                    ->lockForUpdate()
                    ->first();
                if (!$checkResult){
                    $checkResult                = new \App\ExcelCheck();
                    $checkResult->excel_id      = $excel_id;
                    $checkResult->enterprise_id = $enterpriseInfo->id;
                    $checkResult->merchant_id   = $merchant_id ? $merchant_id : 0;
                }
//                $checkResult->error_message = $payload['error_message'] ? json_encode($payload['error_message']) : null;
//                $checkResult->notice = $payload['notice'] ? json_encode($payload['notice']) : null;
                $msg = [
                    'check'=>$payload['error_message'] ? json_encode($payload['error_message']) : null,
                ];
                $checkResult->error_message = json_encode($msg);
                $msg = [
                    'check'=>$payload['notice'] ? json_encode($payload['notice']) : null,
                ];
                $checkResult->notice = json_encode($msg);
                if (count($payload['error_message']) == 0){
                    $checkResult->allow_import = 1;
                }
                $checkResult->total_num = $excelCheck->getTotalNum();
                $checkResult->save();
                DB::commit();
                return response()->json(['level'=>'success','message'=>'检查完成，请查看预览','data'=>['info'=>$payload,'check_result'=>$checkResult]]);
            }
        } catch (\Exception $exception){
            DB::rollBack();
            Log::error('ExcelController:checkExcel=>'.$exception->getMessage());
            return response()->json(['level'=>'error','message'=>'检查过程中系统发生错误：'.$exception->getMessage(),'data'=>$payload]);
        }

    }

    public function confirmImportStandardMedicine(Request $request){
//        $time=microtime(1);
        /** @var User $merchantUser */
        $merchantUser = MerchantManager::isLogin($request);
        if(!$merchantUser)
            return response()->json(['level' => 'error','message' => '请先登录！','data' => 'no_login']);
//        $excel_id       = $request->input('excel_id');
        $excel_check_id       = $request->input('excel_check_id');
        $merchant_id    = $request->input('merchant_id');

        $enterpriseInfo = MerchantManager::getMerchantInfoByUserId($merchantUser->id);
        if(!$enterpriseInfo)
            return response()->json(['level' => 'error','message' => '商家信息异常']);

        if (!$excel_check_id)
            return response()->json(['level'=>'error','message'=>'参数错误','data'=>'']);

        $excel_check_record = \App\ExcelCheck::whereId($excel_check_id)->first();
        if (!$excel_check_record){
            return response()->json(['level' => 'error','message' => '无表格检查记录']);
        }
        $thisExcel = Excels::whereId($excel_check_record->excel_id)->first();
        if (!$thisExcel)
            return response()->json(['level'=>'error','message'=>'excel不存在','data'=>'']);
        $result = $this->dispatch(new StandardMedicineImportHandler($thisExcel->id,$enterpriseInfo->id,$merchant_id,$excel_check_record->id));
        return response()->json(['level'=>'success','message'=>'导入任务提交成功，预计5分钟内导入完成']);
    }

    public function getImportStatus(Request $request){
        $excel_check_id       = $request->input('excel_check_id');
        if ($excel_check_id && !is_numeric($excel_check_id)){
            return response()->json(['level'=>'error','message'=>'查询的参数错误']);
        }

        $data = ['status_name'=>'等待处理','progress'=>['now'=>0,'total'=>0],'is_success'=>0];
        if ($excel_check_id){
            $status_array = Redis::get('job.xlsx.st'.$excel_check_id);
            if ($status_array){
                $status_array = json_decode($status_array);
                if (isset($status_array->now) && isset($status_array->total)){
                    $data['status_name']        = '疯狂导入中';
                    $data['progress']           = $status_array;
                    if ($status_array->now == $status_array->total){
                        $data['status_name']    = '导入已完成';
                        $data['progress']   = $status_array;
                        $data['is_success']     = 1;
                    }
                }

                return response()->json(['level'=>'success','message'=>'success','data'=>$data]);
            } else {
                Log::notice('path to database search');
                $excelCheck = \App\ExcelCheck::whereId($excel_check_id)->first();
                if (!$excelCheck)
                    return response()->json(['level'=>'error','message'=>'查询的数据错误']);
                if (strtotime($excelCheck->created_at) + 60 > time()){
                    $data['status_name']        = $excelCheck->success_import ? '导入成功' : '导入失败';
                    $data['progress']           = ['now'=>$excelCheck->success_num,'total'=>$excelCheck->total_num];
                    if ($excelCheck->success_num >= $excelCheck->total_num)
                        $data['is_success']     = 1;
                } else {
                    $data['status_name']        = '等待中';
                    $data['progress']           = ['now'=>$excelCheck->success_num,'total'=>$excelCheck->total_num];
                }

                return response()->json(['level'=>'success','message'=>'success','data'=>$data]);
            }

        } else {
            return response()->json(['level'=>'success','message'=>'success','data'=>$data]);
        }

    }

    public function test(){
//        DB::beginTransaction();
//        /** @var \App\ExcelCheck $record */
//        $record = \App\ExcelCheck::whereId(1)->lockForUpdate()->first();
//        $record->notice = 'fpm';
//        $record->save();
//        sleep(26);
//        DB::commit();
        return date('Y-m-d H:i:s');
    }
}
